<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, viewport-fit=cover" />
  <meta name="format-detection" content="telephone=no" />
  <title>图片上传</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    body {
      padding: 20px;
      color: #333;
      line-height: 1.5;
    }

    .imageList {
      width: 100%;
      font-size: 0;
      line-height: 0;
    }
    .imageList .imgItem,
    .imageList .addItem {
      display: inline-block;
      width: 90px;
      height: 90px;
      margin: 0 10px 10px 0;
      position: relative;
      font-size: 14px;
      line-height: 20px;
      vertical-align: top;
    }
    .imageList .addItem {
      background: url('./images/upload_img_add.png');
      background-size: 100% 100%;
    }
    .imageList .imgItem img {
      width: 100%;
      height: 100%;
    }
    .imageList .imgItem .title {
      width: 100%;
      height: 20px;
      margin: 0;
      background: rgba(0,0,0,0.5);
      position: absolute;
      bottom: 0;
      left: 0;
      text-align: center;
      color: #fff;
    }
    .imageList .imgItem .del {
      width: 15px;
      height: 15px;
      border-radius: 100%;
      position: absolute;
      top: -4px;
      right: -5px;
      background: url('./images/upload_img_del.png');
      background-size: 100% 100%;
      cursor: pointer;
    }
  </style>
</head>

<body>
  <div style="width: 500px;">
    <ul class="imageList">
      <li class="imgItem">
        <img alt="" src="./images/bg.jpg" >
        <p class="title" title="标题">标题</p>
        <span class="del" title="删除" onclick="$(this).closest('.imgItem').remove()"></span>
      </li>
      <li id="uploadImgBtn" class="addItem"></li>
    </ul>
  </div>

  <script src="https://cdn.bootcss.com/jquery/2.1.0/jquery.min.js"></script>
	
  <script>
    $.fn.imageUpload = function (opt) {
      var $dom = $(this);
			console.log(this);
      var option = {
        multiple: true, // 是否允许多文件上传
        accept: '.jpg,.jpeg,.png,.gif,.bmp,.tiff', // 限制文件类型
        fileSize: 0, // 限制文件大小 0表示不限制 单位：Byte
        compress: true, // 是否压缩
        compressRate: 1, // 压缩率 0 ~ 1
        callback: function (data) {
          // console.log(data);
        },
				
      };
      $.extend(option, opt);

      var upload = {
        bindUploadFun:function ($fileInput, option) {
          var _this = this;
          $fileInput.on("change", function () {
            if (this.files.length === 0) {
              return;
            }
            if (option.fileSize && _this.isOverSize(this.files, option.fileSize)) {
              option.callback && option.callback({
                errorMsg: '文件大小超出限制'
              });
              return;
            }
            if (option.fileSize && _this.isAllowType(this.files)) {
              option.callback && option.callback({
                errorMsg: '请选择图片文件'
              });
              return;
            }

            for (var i = 0, leng = this.files.length; i < leng; i++) {
              // FileReader 对文件进行处理
              var file = this.files[i],
                fileReader = new FileReader();
              // fileReader.readAsText(file); // 读取文件内容              
              fileReader.readAsDataURL(file); // base64方式读取
              fileReader.onload = function () {
                var dataUrl = this.result;
                // console.log(dataUrl);
                // return;
                if (option.compress) {
                  _this.canvasCompress(
                    dataUrl,
                    function (data) {
                      _this.fileReaderLoad(data, file, option.callback);
                    },
                    option.compressRate
                  );
                } else {
                  _this.fileReaderLoad(dataUrl, file, option.callback);
                }
              };
            }
          });
        },
        isAllowType: function(flies) {
          // 文件类型是否错误
          var isError = false;
          for (var i = 0, leng = flies.length; i < leng; i++) {
            if (!isError) {
              isError = !/^image\/\w+$/.test(flies[i].type);
            }
          }
          return isError;
        },
        isOverSize: function(flies, size) {
          // 文件是否超过限制大小
          var isOver = false;
          for (var i = 0, leng = flies.length; i < leng; i++) {
            // console.log(flies[i]);
            if (!isOver) {
              isOver = flies[i].size > size;
            }
          }
          return isOver;
        },
        fileReaderLoad: function (b64DataUrl, file, callback) {
          // 读取文件后的处理
          var blob = this.b64toBlob(b64DataUrl.split(",")[1], file.type),
            formData = new FormData();
          formData.append("fileContent", blob, file.name);
          callback && callback({
            b64DataUrl: b64DataUrl,
            formData: formData,
            file: file
          });
        },
        canvasCompress: function (b64DataUrl, callback, quality) {
          // 用 canvas 压缩处理
          var image = new Image();
          image.src = b64DataUrl;
          image.onload = function () {
            var canvas = document.createElement("canvas"),
              width = image.width,
              height = image.height,
              dataURL = "";
            canvas.width = width;
            canvas.height = height;
            canvas.getContext("2d").drawImage(image, 0, 0, width, height);
            dataURL = canvas.toDataURL("image/jpeg", quality);
            callback && callback(dataURL);
          };
        },
        b64toBlob: function (b64Data, contentType, sliceSize) {
          // base64数据转换为Blob
          contentType = contentType || "";
          sliceSize = sliceSize || 512;
          var byteCharacters = atob(b64Data);
          var byteArrays = [];
          for (
            var offset = 0; offset < byteCharacters.length; offset += sliceSize
          ) {
            var slice = byteCharacters.slice(offset, offset + sliceSize);
            var byteNumbers = new Array(slice.length);
            for (var i = 0; i < slice.length; i++) {
              byteNumbers[i] = slice.charCodeAt(i);
            }
            var byteArray = new Uint8Array(byteNumbers);
            byteArrays.push(byteArray);
          }
          var blob = new Blob(byteArrays, {
            type: contentType
          });
          return blob;
        },
        
				init: function () {
          var $fileInput = $(
            '<input style="position:absolute;top:0;left:0;width:100%;height:100%;opacity:0;" '+
            (option.multiple ? 'multiple="multiple" ' : '') + 
            ' type="file" accept="'+ option.accept +'" name="fileContent">'
          );
          $dom.css("position", "relative");
          $dom.append("<form></form>");
          $dom.find("form").html($fileInput);
          $dom.on("click", function () {});
          this.bindUploadFun($fileInput, option);
        }
      };
      upload.init();


    };


    $("#uploadImgBtn").imageUpload({
      url: "./js/demo.json",
      multiple: true,
      fileSize: 1024 * 1024 * 5, // 5M
      callback: function (data) {
        if (data.errorMsg) {
          alert(data.errorMsg);
          return;
        }
        $('.imageList .addItem').before(
          '<li class="imgItem">'+
            '<img src="'+ data.b64DataUrl +'" >'+
            '<p class="title" title="'+ data.file.name +'">'+ data.file.name +'</p>'+
            '<span class="del" title="删除" onclick="$(this).closest(\'.imgItem\').remove()"></span>'+
          '</li>'
        );
        
				console.log(data.b64DataUrl);
				console.log(data.formData);

        // $.ajax('', {
        //   method: "POST",
        //   data: data.formData,
        //   processData: false,
        //   contentType: false,
        //   success: function () {
        //     console.log('Upload success');
        //   },
        //   error: function () {
        //     console.log('Upload error');
        //   }
        // });

        // console.log(data);
      }
    });






























  </script>
</body>

</html>